package cn.monkey.transport.core;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public abstract class AbstractExchangeManager<C, EXCHANGE extends Exchange> implements ExchangeManager<C, EXCHANGE> {

    protected final ExchangeFactory<C, EXCHANGE> factory;

    protected volatile Map<String, EXCHANGE> exchangeMap;

    public AbstractExchangeManager(ExchangeFactory<C, EXCHANGE> factory) {
        this.factory = factory;
        this.exchangeMap = new ConcurrentHashMap<>();
    }

    @Override
    public EXCHANGE findOrCreate(String key, C c) {
        EXCHANGE exchange = this.exchangeMap.get(key);
        if (exchange != null && exchange.isActive()) {
            return exchange;
        }
        return this.exchangeMap.compute(key, (k, v) -> {
            if (v == null || !v.isActive()) {
                return this.factory.apply(k, v, c);
            }
            return v;
        });
    }

    @Override
    public void destroy(EXCHANGE exchange) {
        Iterator<Map.Entry<String, EXCHANGE>> iterator = this.exchangeMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, EXCHANGE> e = iterator.next();
            Exchange value = e.getValue();
            if (value == exchange) {
                value.destroy();
                iterator.remove();
                break;
            }
            if (value instanceof DelegatesExchange delegatesExchange) {
                Collection<Exchange> delegates = delegatesExchange.delegates();
                if (!delegates.contains(exchange)) {
                    continue;
                }
                delegatesExchange.destroy(exchange);
                boolean b = delegates.stream().noneMatch(Exchange::isActive);
                if (b) {
                    iterator.remove();
                    break;
                }
            }
        }
        throw new IllegalArgumentException("exchange not exists");
    }
}
